package com.wa.aop;

import cn.hutool.core.annotation.AnnotationUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * 切面类
 *
 * @author lfy
 * @Aspect： 告诉Spring当前类是一个切面类
 */
@Aspect
public class LogAspects {

    //抽取公共的切入点表达式
    //1、本类引用
    //2、其他的切面引用
    //3、||表示或者关系
    @Pointcut("execution(public int com.wa.aop.MathCalculator.*(..))||execution(public int com.wa.aop.MathCalculator2.*(..))")
//    @Pointcut(value = "@annotation(com.allchips.beans.policy.annotation.SensorsEvent)")     //注解
    public void pointCut() {
    }

    ;

    //@Before在目标方法之前切入；切入点表达式（指定在哪个方法切入）
    @Before("pointCut()")
    public void logBefore(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        System.out.println("" + joinPoint.getSignature().getName() + "运行。。。@Before:参数列表是：{" + Arrays.asList(args) + "}");
    }

    @After("com.wa.aop.LogAspects.pointCut()")
    public void logAfter(JoinPoint joinPoint) {
        System.out.println("" + joinPoint.getSignature().getName() + "结束。。。@After");
    }

    //JoinPoint一定要出现在参数表的第一位
    @AfterReturning(value = "pointCut()", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        //获取注解值
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Integer eventCode = AnnotationUtil.getAnnotationValue(methodSignature.getMethod(), Deprecated.class);

        System.out.println("" + joinPoint.getSignature().getName() + "正常返回。。。@AfterReturning:运行结果：{" + result + "}");
    }

    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void logEAfterThrowing(JoinPoint joinPoint, Exception exception) {
        System.out.println("" + joinPoint.getSignature().getName() + "异常。。。异常信息：{" + exception + "}");
    }

    @Around(value = "pointCut()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        //继续下一个建议或目标方法调用
        System.out.println("" + joinPoint.getSignature().getName() + "@Around之前:");
        Object result = null;
        try {
            result = joinPoint.proceed();
        } catch (Exception e) {
            //有异常会到这里
            e.printStackTrace();
        }
        System.out.println("" + joinPoint.getSignature().getName() + "@Around之后:");
        //此连接点处的参数
        Object[] params = joinPoint.getArgs();
        //连接点的签名。
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        //声明此成员的类、接口或方面
        Class clazz = methodSignature.getDeclaringType();
        //获得方阿飞
        Method method = clazz.getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        // 方法参数的注解
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        return result;
    }

}
